import { Body, Controller, Delete, Get, Post, Put, Query } from '@nestjs/common'
import { ApiOperation, ApiTags } from '@nestjs/swagger'

import { ApiResult } from '~/common/decorators/api-result.decorator'
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator'
import { DeleteDto } from '~/common/dto/delete.dto'
import { BusinessException } from '~/common/exceptions/biz.exception'
import { CreatorPipe } from '~/common/pipes/creator.pipe'
import { UpdaterPipe } from '~/common/pipes/updater.pipe'
import { ErrorEnum } from '~/constants/error-code.constant'
import { Pagination } from '~/helper/paginate/pagination'
import { MenuService } from '~/modules/system/menu/menu.service'

import { definePermission, Perm } from '../auth/decorators/permission.decorator'

import { UserPasswordDto } from './dto/password.dto'
import { UserPageDto, UserQueryDto, UserSaveDto } from './dto/user.dto'
import { UserEntity } from './user.entity'
import { UserService } from './user.service'

export const permissions = definePermission('system:user', {
  PAGE: 'page',
  QUERY: 'query',
  CREATE: 'create',
  UPDATE: 'update',
  DELETE: 'delete',

  PASSWORD_UPDATE: 'password:update',
  PASSWORD_RESET: 'pass:reset',
} as const)

@ApiTags('System - 用户模块')
@ApiSecurityAuth()
@Controller('user')
export class UserController {
  constructor(
    private userService: UserService,
    private menuService: MenuService,
  ) {}

  @Get('page')
  @ApiOperation({ summary: '获取用户分页列表' })
  @ApiResult({ type: [UserPageDto], isPage: true })
  @Perm(permissions.PAGE)
  async page(@Query() dto: UserQueryDto): Promise<Pagination<UserPageDto>> {
    return this.userService.page(dto)
  }

  @Get('simple-list')
  @ApiOperation({ summary: '获取用户列表' })
  @ApiResult({ type: [UserEntity] })
  async list(@Query() dto: UserQueryDto): Promise<UserEntity[]> {
    return this.userService.list(dto)
  }

  @Get('get')
  @ApiOperation({ summary: '查询用户详情' })
  @ApiResult({ type: UserEntity })
  @Perm(permissions.QUERY)
  async get(@Query('id') id: number): Promise<UserEntity> {
    return this.userService.info(id)
  }

  @Post('create')
  @ApiOperation({ summary: '创建用户' })
  @Perm(permissions.CREATE)
  async create(@Body(CreatorPipe) dto: UserSaveDto): Promise<void> {
    await this.userService.create(dto)
  }

  @Put('update')
  @ApiOperation({ summary: '更新用户' })
  @Perm(permissions.UPDATE)
  async update(@Body(UpdaterPipe) dto: UserSaveDto): Promise<void> {
    if (!dto.id) {
      throw new BusinessException(ErrorEnum.REQUESTED_RESOURCE_NOT_FOUND)
    }

    await this.userService.update(dto.id, dto)
    await this.menuService.refreshPerms(dto.id)
  }

  @Delete('delete')
  @ApiOperation({ summary: '删除单个用户' })
  @Perm(permissions.DELETE)
  async delete(@Query('id') id: number): Promise<void> {
    if (!id || Number.isNaN(id)) {
      throw new BusinessException(ErrorEnum.REQUESTED_RESOURCE_NOT_FOUND)
    }

    await this.userService.delete([id])
    await this.userService.multiForbidden([id])
  }

  @Delete('delete-list')
  @ApiOperation({ summary: '批量删除用户' })
  @Perm(permissions.DELETE)
  async deleteList(@Query() dto: DeleteDto): Promise<void> {
    // 解析ids参数
    const ids = dto.ids.split(',').map(id => Number.parseInt(id.trim())).filter(id => !Number.isNaN(id))

    if (ids.length === 0) {
      throw new BusinessException(ErrorEnum.REQUESTED_RESOURCE_NOT_FOUND)
    }

    await this.userService.delete(ids)
    await this.userService.multiForbidden(ids)
  }

  @Post('password')
  @ApiOperation({ summary: '更改用户密码' })
  @Perm(permissions.PASSWORD_UPDATE)
  async password(@Query('id') id: number, @Body() dto: UserPasswordDto): Promise<void> {
    await this.userService.forceUpdatePassword(id, dto.password)
  }
}
